package net

import (
	"github.com/gorilla/websocket"
	"go.uber.org/zap"
	"net/http"
	"sync"
)

var (
	websocketUpgrade = websocket.Upgrader{
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
		ReadBufferSize:  1024,
		WriteBufferSize: 1024,
	}
)

type CheckOriginHandler func(r *http.Request) bool

/*
*
websocket管理器
创建ws服务
*/
type Manager struct {
	sync.RWMutex
	websocketUpgrade   *websocket.Upgrader
	ServerId           string
	CheckOriginHandler CheckOriginHandler
	clients            map[string]Connection //看这里，Connection为接口的类型
	ClientReadChan     chan *MsgPack         //读取消息（客户端的连接等）
}

/*
*
实例化管理器(这方法没有接收器)
*/
func NewManager() *Manager {
	return &Manager{
		ClientReadChan: make(chan *MsgPack, 1024),
		clients:        make(map[string]Connection),
	}
}

/*
*
启动websocket服务入口
*/
func (m *Manager) Run(addr string) {
	//todo
	http.HandleFunc("/", m.ServeWs)
}

func (m *Manager) ServeWs(w http.ResponseWriter, r *http.Request) {
	//websocket基于http
	if m.websocketUpgrade == nil {
		m.websocketUpgrade = &websocketUpgrade //全局变量赋值到这里
	}
	wsConn, err := m.websocketUpgrade.Upgrade(w, r, nil)
	if err != nil {
		zap.S().Errorf("websocketUpgrade.Upgrade err:%v", err)
		return
	}
	client := NewWsConnection(wsConn, m)
	//将当前连接的客户端存储起来
	m.addClient(client)
	client.Run() //开放读写操作
}

func (m *Manager) addClient(client *WsConnection) {
	m.Lock()
	defer m.Unlock()
	m.clients[client.Cid] = client
}

func (m Manager) removeClient(client *WsConnection) {
	for cid, v := range m.clients {
		if cid == client.Cid {
			delete(m.clients, cid)
			v.Close()
		}
	}
}
